package KNNCalculate;

import java.util.*;
import java.util.Map.Entry;


public class IG extends AnswerList{
    public HashMap<String, Double> map = new HashMap<String, Double>();

    public HashMap<String, Double> IG_Cal(HashMap<String,ArrayList<Short>> list_){
        Iterator<Entry<String, ArrayList<Short>>> iter =list_.entrySet().iterator();
        double entropy = Math.log(classNumber);
        while (iter.hasNext()){
            Entry<String, ArrayList<Short>> entry = iter.next();
            String word = entry.getKey();
            ArrayList<Short> al = entry.getValue();
            int category =ListNumber;
            int wcount = 0; 
            int[] wcount_class = new int[classNumber];// 
            double pw = 0.0; 
            double[] pcw = new double[classNumber]; 
            double[] pcw_b = new double[classNumber]; 
            for (int i = 0; i < classNumber; i++) {
                for (int j = 0; j < category; j++) {
                    if (al.get(j + i * category) > 0) {
                        wcount_class[i]++;
                    }
                }
                wcount += wcount_class[i];
            }
            pw = 1.0 * wcount / num;
            for (int i = 0; i < classNumber; i++) {
                pcw[i] = 1.0 * wcount_class[i] / wcount;
                pcw_b[i] = 1.0 * (category - wcount_class[i])
                        / (num - wcount);
            }
            double d1 = 0.0;
            double d2 = 0.0;
            for (int i = 0; i < classNumber; i++) {
                d1 += pcw[i] * Math.log(pcw[i] + Double.MIN_VALUE);
                d2 += pcw_b[i] * Math.log(pcw_b[i] + Double.MIN_VALUE);
            }
            double ig = entropy + pw * d1 + (1.0 - pw) * d2;
            this.map.put(word, ig);
            System.out.println(word+"\t"+ig);
        }
        return this.map;
    }

    public ArrayList<Map.Entry<String,Double>> sort(HashMap<String,Double> arg){
        ArrayList<Map.Entry<String,Double>> al=new ArrayList<Map.Entry<String,Double>>(arg.entrySet());
        Collections.sort(al, new Comparator<Map.Entry<String,Double>>(){
            public int compare(Map.Entry<String, Double> o1,Map.Entry<String,Double> o2){
                double res=o2.getValue()-o1.getValue();
                if(res<0)
                    return -1;
                else if(res>0)
                    return 1;
                else
                    return 0;
            }
        });
        return al;
    }
}